home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Shells / tcsh / Source / tw.help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  6.0 KB  |  202 lines

  1. /* $Header: /u/christos/src/tcsh-6.03/RCS/tw.help.c,v 3.9 1992/09/18 20:56:35 christos Exp $ */
  2. /* tw.help.c: actually look up and print documentation on a file.
  3.  *          Look down the path for an appropriate file, then print it.
  4.  *          Note that the printing is NOT PAGED.  This is because the
  5.  *          function is NOT meant to look at manual pages, it only does so
  6.  *          if there is no .help file to look in.
  7.  */
  8. /*-
  9.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  10.  * All rights reserved.
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, are permitted provided that the following conditions
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  * 3. All advertising materials mentioning features or use of this software
  21.  *    must display the following acknowledgement:
  22.  *    This product includes software developed by the University of
  23.  *    California, Berkeley and its contributors.
  24.  * 4. Neither the name of the University nor the names of its contributors
  25.  *    may be used to endorse or promote products derived from this software
  26.  *    without specific prior written permission.
  27.  *
  28.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  29.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  32.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  37.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  38.  * SUCH DAMAGE.
  39.  */
  40. #include "sh.h"
  41.  
  42. RCSID("$Id: tw.help.c,v 3.9 1992/09/18 20:56:35 christos Exp $")
  43.  
  44. #include "tw.h"
  45. #include "tc.h"
  46.  
  47.  
  48. static int f = -1;
  49. static    sigret_t     cleanf        __P((int));
  50. static    Char        *skipslist    __P((Char *));
  51. static    void         nextslist     __P((Char *, Char *));
  52.  
  53. static char *h_ext[] = {
  54.     ".help", ".1", ".8", ".6", "", NULL
  55. };
  56.  
  57. void
  58. do_help(command)
  59.     Char   *command;
  60. {
  61.     Char    name[FILSIZ + 1];
  62.     Char   *cmd_p, *ep;
  63.     char  **sp;
  64.  
  65.     sigret_t(*orig_intr) ();
  66.     Char    curdir[MAXPATHLEN];    /* Current directory being looked at */
  67.     register Char *hpath;    /* The environment parameter */
  68.     Char    full[MAXPATHLEN];
  69.     char    buf[512];        /* full path name and buffer for read */
  70.     int     len;        /* length of read buffer */
  71.     Char   *thpath;
  72.  
  73.  
  74.     /* trim off the whitespace at the beginning */
  75.     for (cmd_p = command; *cmd_p == ' ' || *cmd_p == '\t'; cmd_p++)
  76.     continue;
  77.         
  78.     /* copy the string to a safe place */
  79.     copyn(name, cmd_p, FILSIZ + 1);
  80.  
  81.     /* trim off the whitespace that may be at the end */
  82.     for (cmd_p = name; 
  83.      *cmd_p != ' ' && *cmd_p != '\t' && *cmd_p != '\0'; cmd_p++)
  84.     continue;
  85.     *cmd_p = '\0';
  86.  
  87.     /* if nothing left, return */
  88.     if (*name == '\0')
  89.     return;
  90.  
  91.     if (adrof1(STRhelpcommand, &aliases)) {    /* if we have an alias */
  92.     jmp_buf_t osetexit;
  93.  
  94.     getexit(osetexit);    /* make sure to come back here */
  95.     if (setexit() == 0)
  96.         aliasrun(2, STRhelpcommand, name);    /* then use it. */
  97.     resexit(osetexit);    /* and finish up */
  98.     }
  99.     else {            /* else cat something to them */
  100.     /* got is, now "cat" the file based on the path $HPATH */
  101.  
  102.     hpath = str2short(getenv(SEARCHLIST));
  103.     if (hpath == NULL)
  104.         hpath = str2short(DEFAULTLIST);
  105.     thpath = hpath = Strsave(hpath);
  106.  
  107.     for (;;) {
  108.         if (!*hpath) {
  109.         xprintf("No help file for %S\n", name);
  110.         break;
  111.         }
  112.         nextslist(hpath, curdir);
  113.         hpath = skipslist(hpath);
  114.  
  115.         /*
  116.          * now make the full path name - try first /bar/foo.help, then
  117.          * /bar/foo.1, /bar/foo.8, then finally /bar/foo.6.  This is so
  118.          * that you don't spit a binary at the tty when $HPATH == $PATH.
  119.          */
  120.         copyn(full, curdir, sizeof(full) / sizeof(Char));
  121.         catn(full, STRslash, sizeof(full) / sizeof(Char));
  122.         catn(full, name, sizeof(full) / sizeof(Char));
  123.         ep = &full[Strlen(full)];
  124.         for (sp = h_ext; *sp; sp++) {
  125.         *ep = '\0';
  126.         catn(full, str2short(*sp), sizeof(full) / sizeof(Char));
  127.         if ((f = open(short2str(full), O_RDONLY)) != -1)
  128.             break;
  129.         }
  130.         if (f != -1) {
  131.         /* so cat it to the terminal */
  132.         orig_intr = (sigret_t (*)()) sigset(SIGINT, cleanf);
  133.         while (f != -1 && (len = read(f, (char *) buf, 512)) != 0)
  134.             (void) write(SHOUT, (char *) buf, (size_t) len);
  135.         (void) sigset(SIGINT, orig_intr);
  136.         if (f != -1)
  137.             (void) close(f);
  138.         break;
  139.         }
  140.     }
  141.     xfree((ptr_t) thpath);
  142.     }
  143. }
  144.  
  145. static  sigret_t
  146. /*ARGSUSED*/
  147. cleanf(snum)
  148. int snum;
  149. {
  150. #ifdef UNRELSIGS
  151.     if (snum)
  152.     (void) sigset(SIGINT, cleanf);
  153. #endif /* UNRELSIGS */
  154.     if (f != -1)
  155.     (void) close(f);
  156.     f = -1;
  157. #ifndef SIGVOID
  158.     return (snum);
  159. #endif
  160. }
  161.  
  162. /* these next two are stolen from CMU's man(1) command for looking down
  163.  * paths.  they are prety straight forward. */
  164.  
  165. /*
  166.  * nextslist takes a search list and copies the next path in it
  167.  * to np.  A null search list entry is expanded to ".".
  168.  * If there are no entries in the search list, then np will point
  169.  * to a null string.
  170.  */
  171.  
  172. static void
  173. nextslist(sl, np)
  174.     register Char *sl;
  175.     register Char *np;
  176. {
  177.     if (!*sl)
  178.     *np = '\000';
  179.     else if (*sl == ':') {
  180.     *np++ = '.';
  181.     *np = '\000';
  182.     }
  183.     else {
  184.     while (*sl && *sl != ':')
  185.         *np++ = *sl++;
  186.     *np = '\000';
  187.     }
  188. }
  189.  
  190. /*
  191.  * skipslist returns the pointer to the next entry in the search list.
  192.  */
  193.  
  194. static Char *
  195. skipslist(sl)
  196.     register Char *sl;
  197. {
  198.     while (*sl && *sl++ != ':')
  199.     continue;
  200.     return (sl);
  201. }
  202.